<script setup lang="ts">
import { MoreOutlined } from '@ant-design/icons-vue'
import type { MenuProps } from 'ant-design-vue'
import type { MenuReq, MenuResp } from '~/api/setting/model/menu.ts'
import { queryMenuCheckedTreeListOfPermissionIdApi } from '~/api/setting/menu.ts'
import { bindPermissionMenuRelationApi, unBindPermissionMenuRelationApi } from '~/api/setting/permission.ts'
import type { PermissionMenuReq } from '~/api/setting/model/permission-menu.ts'

const props = defineProps({
  permissionData: Object,
})

const emits = defineEmits(['onAuthSuccess'])

const message = useMessage()

const expandedKeys = ref<(string | number)[]>([])
const searchValue = shallowRef('')
const autoExpandParent = ref<boolean>(true)
const checkedKeys = ref<(string | number)[]>([])

const loading = shallowRef(false)
const treeData = shallowRef<any[]>([])

/**
 * 菜单树展开菜单列表
 */
const dataList = shallowRef<MenuResp[]>([])

/**
 * 初始化菜单树数据
 */
async function init() {
  if (loading.value) {
    return
  }
  loading.value = true
  try {
    const menuReq: MenuReq = {
      permissionId: props.permissionData?.id,
    }
    const menuTreeData = await queryMenuCheckedTreeListOfPermissionIdApi(menuReq)

    checkedKeys.value = []
    dataList.value = []
    generateList(menuTreeData)

    treeData.value = menuTreeData
    getAllParentKeys(treeData.value, expandedKeys.value)
  } catch (e) {
    console.log(e)
  } finally {
    loading.value = false
  }
}

/**
 * 递归菜单树展开菜单列表
 * @param tree 菜单树
 */
function generateList(tree: MenuResp[]) {
  for (let i = 0; i < tree?.length; i++) {
    const node = tree[i]

    node.disabled = (!(node.stateId === 1))

    dataList.value.push(node)
    if (node.checked === true && node.id) {
      checkedKeys.value.push(node.id)
    }

    if (node.children) {
      generateList(node.children)
    }
  }
}

/**
 * 获取菜单名称模糊查询到的树节点
 * @param key 菜单名称
 * @param tree 菜单树
 */
function getParentKey(key: string | number, tree: MenuResp[]): string | number {
  let parentKey: any
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i]
    if (node.children) {
      if (node.children.some(item => item.id === key)) {
        parentKey = node.id
      } else if (getParentKey(key, node.children)) {
        parentKey = getParentKey(key, node.children)
      }
    }
  }
  return parentKey
}

/**
 * 获取全部的父级菜单
 *
 * @param tree 菜单树形菜单
 * @param allParentKeys 全部的父级节点
 */
function getAllParentKeys(tree: MenuResp[], allParentKeys: (string | number)[]) {
  if (!tree) {
    return
  }

  for (let i = 0; i < tree.length; i++) {
    const node = tree[i]
    if (node.children) {
      if (node.id) {
        allParentKeys.push(node.id)
      }
      getAllParentKeys(node.children, allParentKeys)
    }
  }
}

async function onSearch() {

}

/**
 * 树展开
 * @param keys 展开父级节点集合
 */
function onExpand(keys: (string | number)[]) {
  expandedKeys.value = keys
}

/**
 * 树展开折叠
 * @param e
 */
const handleMenuClick: MenuProps['onClick'] = (e) => {
  expandedKeys.value = []
  if (e.key === 'expandAll') {
    getAllParentKeys(treeData.value, expandedKeys.value)
  }
}

async function onClose() {
  emits('onAuthSuccess')
}

function onTreeCheck(checkedKeys, { checked, node }) {
  console.log('onTreeCheck', checkedKeys)
  if (checked) {
    authMenu(node)
  } else {
    unAuthMenu(node)
  }
}

/**
 * 授权功能
 *
 * @param menuResp
 */
async function authMenu(menuResp: MenuResp) {
  const close = message.loading('授权中......')
  try {
    if (menuResp.children && menuResp.children?.length > 0) {
      message.success('请勾选子菜单（菜单节点不支持）')
      return
    }
    const permissionMenuReq: PermissionMenuReq = {
      permissionId: props?.permissionData?.id,
      menuId: menuResp.id,
    }
    const isAuth = await bindPermissionMenuRelationApi(permissionMenuReq)
    if (isAuth) {
      message.success('授权成功')
      await init()
    }
  } catch (e) {
    console.log(e)
  } finally {
    close()
  }
}

/**
 * 解除授权功能
 *
 * @param menuResp
 */
async function unAuthMenu(menuResp: MenuResp) {
  const close = message.loading('取消授权中......')
  try {
    if (menuResp.children && menuResp.children?.length > 0) {
      message.success('请勾选子菜单（菜单节点不支持）')
      return
    }
    const permissionMenuReq: PermissionMenuReq = {
      permissionId: props?.permissionData?.id,
      menuId: menuResp.id,
    }
    const isAuth = await unBindPermissionMenuRelationApi(permissionMenuReq)
    if (isAuth) {
      message.success('授权取消成功')
      await init()
    }
  } catch (e) {
    console.log(e)
  } finally {
    close()
  }
}

watch(searchValue, (value) => {
  expandedKeys.value = dataList.value
    .map((item: MenuResp[][number]) => {
      if (item?.menuTitle?.includes(value) && item.id) {
        return getParentKey(item.id, treeData.value)
      }

      return ''
    })
    .filter((item, i, self) => item && self.indexOf(item) === i)
  searchValue.value = value
  autoExpandParent.value = true
})

onMounted(() => {
  init()
})
</script>

<template>
  <a-modal
    title="授权菜单"
    width="600px"
    footer=""
    @close="onClose"
  >
    <a-space direction="vertical" size="large" class="w-full">
      <a-card title="菜单列表">
        <template #extra>
          <a-flex gap="small" align="center">
            <a-input-search
              v-model:value="searchValue"
              placeholder="搜索"
              style="width: 200px"
              allow-clear
              @search="onSearch"
            />
            <a-dropdown>
              <template #overlay>
                <a-menu @click="handleMenuClick">
                  <a-menu-item key="expandAll">
                    展开全部
                  </a-menu-item>
                  <a-menu-item key="unExpandAll">
                    折叠全部
                  </a-menu-item>
                </a-menu>
              </template>
              <MoreOutlined :font-size="6" />
            </a-dropdown>
          </a-flex>
        </template>
        <a-tree
          v-if="autoExpandParent && treeData && treeData.length > 0"
          :tree-data="treeData"
          :field-names="{ key: 'id', title: 'menuTitle' }"
          :expanded-keys="expandedKeys"
          :checked-keys="checkedKeys"
          :auto-expand-parent="autoExpandParent"
          checkable
          @expand="onExpand"
          @check="onTreeCheck"
        >
          <template #title="{ menuTitle, stateId }">
            <span v-if="menuTitle.indexOf(searchValue) > -1">
              {{ menuTitle.substring(0, menuTitle.indexOf(searchValue)) }}
              <span style="color: #f50">{{ searchValue }}</span>
              {{ menuTitle.substring(menuTitle.indexOf(searchValue) + searchValue.length) }}{{ stateId === 1 ? '' : '（无效）' }}
            </span>
            <span v-else>{{ menuTitle }}{{ stateId === 1 ? '' : '（无效）' }}</span>
          </template>
        </a-tree>
      </a-card>
    </a-space>
  </a-modal>
</template>

<style scoped lang="less">

</style>
